package day16;

/*需求:设计多线程编程模型,4个窗口共计售票100张*/
/*本类通过继承Thread类的方式实现多线程售票案例*/
public class TestThread {
    public static void main(String[] args) {
        //5.创建多个线程对象 Ctrl+D 复制当前行
        TicketThread t1 = new TicketThread();
        TicketThread t2 = new TicketThread();
        TicketThread t3 = new TicketThread();
        TicketThread t4 = new TicketThread();
        //6.以多线程的方式启动
        t1.start();
        t2.start();
        t3.start();
        t4.start();
    }
}

//1.自定义线程售票业务类
class TicketThread extends Thread {
    //3.定义变量,用来保存票数
    //int tickets = 100;//不可以,会卖400张票
    //7.解决4个线程卖了400张票的BUG
    static int tickets = 100;//静态资源属于类资源,被全局所有对象共享,只有一份

    //2.把业务写在重写run()里
    @Override
    public void run() {
        //4.通过循环结构来一直卖票
        while (true) {
            synchronized (TicketThread.class) {
                if (tickets > 0) {
                    try {
                        //8.如果数据能够经受住sleep的考验,才能说明数据没有了安全隐患--人为制造问题
                        //问题1:产生了重卖:同一张票卖给了多个人
                        //问题2:产生了超卖:超出了规定票数,甚至卖出了0和-1这样的票数
                        Thread.sleep(10);//让程序休眠10ms
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(getName() + "=" + tickets--);
                }
                //做判断,如果没有票了,就退出死循环
                if (tickets <= 0) break;//注意,死循环一定要设置出口
            }
        }
    }
}